package com.duubee.btframe.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

public class BtHttpClient {

    public static String doGet(String httpurl, JSONObject params, JSONObject headers, HttpServletResponse httpServletResponse) {
        // 获取连接客户端工具
        CloseableHttpClient httpClient = HttpClients.createDefault();

        String entityStr = null;
        CloseableHttpResponse response = null;

        try {
            /*
             * 由于GET请求的参数都是拼装在URL地址后方，所以我们要构建一个URL，带参数
             */
            URIBuilder uriBuilder = new URIBuilder(httpurl);
            /** 第一种添加参数的形式 */
            /*uriBuilder.addParameter("name", "root");
            uriBuilder.addParameter("password", "123456");*/
            if (params != null && params.keySet().size() > 0) {
                for (String key : params.keySet()) {
                    uriBuilder.addParameter(key, params.getString(key));
                }
            }

            HttpGet httpGet = new HttpGet(uriBuilder.build());

            /*
             * 添加请求头信息
             */
            // 浏览器表示
            httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
            // 传输的类型
            httpGet.addHeader("Content-Type", "application/x-www-form-urlencoded");
            //header的<key,value>
            if (headers != null && headers.keySet().size() > 0) {
                for (String key : headers.keySet()) {
                    httpGet.addHeader(key, headers.getString(key));
                }
            }

            // 执行请求
            response = httpClient.execute(httpGet);

            //转发cookie
            processCookie(httpServletResponse, response);


            // 获得响应的实体对象
            HttpEntity entity = response.getEntity();
            // 使用Apache提供的工具类进行转换成字符串
            entityStr = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        } finally {
            // 释放连接
            if (null != response) {
                try {
                    response.close();
                    httpClient.close();
                } catch (IOException e) {
                    System.err.println("释放连接出错");
                    e.printStackTrace();
                }
            }
        }
        return entityStr;
    }


    /**
     * 发送post请求
     *
     * @param url        路径
     * @param jsonObject 参数(json类型)
     * @return
     * @throws ParseException
     * @throws IOException
     */
    public static String doPost(String url, JSONObject jsonObject, JSONObject headers, HttpServletResponse httpServletResponse) throws ParseException, IOException {
        String body = "";

        //创建httpclient对象
        CloseableHttpClient client = HttpClients.createDefault();
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);

        //装填参数
        StringEntity s = new StringEntity(jsonObject.toString(), "utf-8");
        s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                "application/json"));
        //设置参数到请求对象中
        httpPost.setEntity(s);

        //设置header信息
        //指定报文头【Content-type】、【User-Agent】
//        httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
        httpPost.setHeader("Content-type", "application/json");
        httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");


        if (headers != null && headers.keySet().size() > 0) {
            for (String key : headers.keySet()) {
                String value = headers.getString(key);
                if (BtStringUtil.isNotEmpty(value)) {
                    httpPost.setHeader(key, value);
                }
            }
        }


        //执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = client.execute(httpPost);

        //转发cookie
        processCookie(httpServletResponse, response);

        //获取结果实体
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            //按指定编码转换结果实体为String类型
            body = EntityUtils.toString(entity, "utf-8");
        }
        EntityUtils.consume(entity);
        //释放链接
        response.close();

        return body;
    }

    /**
     * 处理转发cookie
     *
     * @param httpServletResponse
     * @param response
     */
    private static void processCookie(HttpServletResponse httpServletResponse, CloseableHttpResponse response) {
        //转发cookie
        if (httpServletResponse != null && response != null) {
            Header[] ssoResponseHeader = response.getHeaders("Set-Cookie");
            if (ssoResponseHeader != null && ssoResponseHeader.length > 0) {
                Arrays.stream(ssoResponseHeader).forEach(header -> {
                    String value = header.getValue();
                    if (BtStringUtil.isNotEmpty(value)) {
                        String[] valueArr = BtStringUtil.stringSplit(value, "; ");
                        if (valueArr != null && valueArr.length > 0) {
                            String[] tempArr = BtStringUtil.stringSplit(valueArr[0], "=");
                            if (tempArr != null && tempArr.length == 2) {
                                Cookie cookie = new Cookie(tempArr[0], tempArr[1]);
                                for (int i = 1; i < valueArr.length; i++) {
                                    tempArr = BtStringUtil.stringSplit(valueArr[i], "=");
                                    if (tempArr != null && (tempArr.length == 2 || tempArr[0].equalsIgnoreCase("secure") || tempArr[0].equalsIgnoreCase("httponly"))) {
                                        switch (tempArr[0].toLowerCase()) {
                                            case "path":
                                                cookie.setPath(tempArr[1]);
                                                break;
                                            case "secure":
                                                if (tempArr.length == 2) {
                                                    cookie.setSecure(Boolean.valueOf(tempArr[1]));
                                                } else {
                                                    cookie.setSecure(true);
                                                }
                                                break;
                                            case "comment":
                                                cookie.setComment(tempArr[1]);
                                                break;
                                            case "domain":
                                                cookie.setDomain(tempArr[1]);
                                                break;
                                            case "httponly":
                                                if (tempArr.length == 2) {
                                                    cookie.setHttpOnly(Boolean.valueOf(tempArr[1]));
                                                } else {
                                                    cookie.setHttpOnly(true);
                                                }
                                                break;
                                            case "maxage":
                                                cookie.setMaxAge(Integer.valueOf(tempArr[1]));
                                                break;
                                            case "version":
                                                cookie.setVersion(Integer.valueOf(tempArr[1]));
                                                break;
                                        }
                                    }
                                }

                                httpServletResponse.addCookie(cookie);
                            }
                        }
                    }
                });
            }
        }
    }
}